package com.koi.system.controller.dictdata;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.koi.common.constants.KoiCacheConstants;
import com.koi.common.constants.KoiConstants;
import com.koi.common.ex.koi.YUtil;
import com.koi.common.redis.RedisUtil;
import com.koi.common.satoken.KoiLoginUtil;
import com.koi.model.vo.system.SysDictDataVo;
import com.koi.pojo.system.SysDictData;
import com.koi.system.service.dictdata.SysDictDataService;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.List;

/**
 * @author ･ᴗ･
 * @description [字典数据表-控制层]
 */
@Validated
@RequestMapping("/koi")
@RequiredArgsConstructor
@RestController
public class SysDictDataController {

    private final SysDictDataService sysDictDataService;

    private final RedisUtil redisUtil;

    /**
     * @description [分页查询]
     * @author ･ᴗ･
     */
    @GetMapping("/sysDictData/listPage")
    public IPage<SysDictData> listPage(SysDictDataVo vo) {
        // 分页构造器
        Page<SysDictData> page = new Page<>(vo.getPageNo(), vo.getPageSize());
        // 条件构造器
        LambdaQueryWrapper<SysDictData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(vo.getDictType()), SysDictData::getDictType, vo.getDictType());
        wrapper.like(StringUtils.isNotBlank(vo.getDictLabel()), SysDictData::getDictLabel, vo.getDictLabel());
        wrapper.eq(StringUtils.isNotBlank(vo.getDictStatus()), SysDictData::getDictStatus, vo.getDictStatus());
        wrapper.orderByDesc(SysDictData::getDictType);
        wrapper.orderByAsc(SysDictData::getSorted);
        // 进行分页查询
        page = sysDictDataService.page(page, wrapper);
        return page;
    }

    /**
     * @description [查询所有]
     * @author ･ᴗ･
     */
    @GetMapping("/sysDictData/list")
    public List<SysDictData> list() {
        return sysDictDataService.list();
    }

    /**
     * @description [根据主键进行查询]
     * @author ･ᴗ･
     */
    @GetMapping("/sysDictData/getById/{id}")
    public SysDictData getById(@PathVariable Long id) {
        return sysDictDataService.getById(id);
    }

    /**
     * @description [新增]
     * @author ･ᴗ･
     */
    @PostMapping("/sysDictData/add")
    public void add(@Validated @RequestBody SysDictData sysDictData) {
        // 查询是否已经存在字典名称
        LambdaQueryWrapper<SysDictData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDictData::getDictLabel, sysDictData.getDictLabel());
        long count = sysDictDataService.count(wrapper);
        YUtil.isTrue(count > 0, "该字典名称已存在，请重新输入");
        if (StringUtils.isNotBlank(KoiLoginUtil.getUserName())) {
            sysDictData.setCreateBy(KoiLoginUtil.getUserName());
        }
        YUtil.isTrue(!sysDictDataService.save(sysDictData), "新增失败，请稍后重试");
        // 同步缓存
        sysDictDataService.listDictCacheRedis();
    }

    /**
     * @description [修改]
     * @author ･ᴗ･
     */
    @PostMapping("/sysDictData/update")
    public void update(@Validated @RequestBody SysDictData sysDictData) {
        // 查询是否已经存在字典名称
        LambdaQueryWrapper<SysDictData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDictData::getDictLabel, sysDictData.getDictLabel());
        SysDictData dictData = sysDictDataService.getOne(wrapper);
        YUtil.isTrue(ObjectUtils.isNotEmpty(dictData) && !dictData.getDictId().equals(sysDictData.getDictId()), "该字典名称已存在，请重新输入");
        if (StringUtils.isNotBlank(KoiLoginUtil.getUserName())) {
            sysDictData.setUpdateBy(KoiLoginUtil.getUserName());
        }
        YUtil.isTrue(!sysDictDataService.updateById(sysDictData), "修改失败，请稍后重试");
        // 同步缓存
        sysDictDataService.listDictCacheRedis();
    }

    /**
     * @description [删除]
     * @author ･ᴗ･
     */
    @PostMapping("/sysDictData/deleteById/{id}")
    public void delete(@PathVariable Long id) {
        YUtil.isTrue(!sysDictDataService.removeById(id), "删除失败，请稍后重试");
        // 同步缓存
        sysDictDataService.listDictCacheRedis();
    }

    /**
     * @description [批量删除]
     * @author ･ᴗ･
     */
    @PostMapping("/sysDictData/batchDelete")
    public void batchDelete(@NotNull(message = "请选择需要删除的数据") @RequestBody List<Long> ids) {
        YUtil.isTrue(!sysDictDataService.removeBatchByIds(ids), "批量删除失败，请稍后重试");
        // 同步缓存
        sysDictDataService.listDictCacheRedis();
    }

    /**
     * @description [修改状态]
     * @author ･ᴗ･
     */
    @PostMapping("/sysDictData/updateStatus/{dictId}/{dictStatus}")
    public void updateStatus(@PathVariable("dictId") Long dictId, @PathVariable("dictStatus") String dictStatus) {
        UpdateWrapper<SysDictData> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("dict_status", dictStatus).eq("dict_id", dictId);
        YUtil.isTrue(!sysDictDataService.update(null, updateWrapper), "修改失败，请稍后重试");
        // 同步缓存
        sysDictDataService.listDictCacheRedis();
    }

    /**
     * @description [根据类型查询字典数据]
     * @author ･ᴗ･
     */
    @GetMapping("/sysDictData/listDataByType/{dictType}")
    public List<SysDictData> listDataByType(@PathVariable("dictType") String dictType) {
        Boolean isExist = redisUtil.hasKey(KoiCacheConstants.DICT_REDIS_KEY + dictType);
        if (!isExist) {
            LambdaQueryWrapper<SysDictData> wrapper = new LambdaQueryWrapper<>();
            // 查询指定字段
            wrapper.select(SysDictData::getDictLabel, SysDictData::getDictValue, SysDictData::getDictType, SysDictData::getDictTag, SysDictData::getDictColor);
            wrapper.eq(StringUtils.isNotBlank(dictType), SysDictData::getDictType, dictType);
            wrapper.eq(SysDictData::getDictStatus, KoiConstants.ZERO_STRING);
            List<SysDictData> dictDataList = sysDictDataService.list(wrapper);
            if (CollectionUtils.isNotEmpty(dictDataList)) {
                return dictDataList;
            } else {
                return Collections.emptyList();
            }
        } else {
            List<SysDictData> redisDictData = redisUtil.getKey(KoiCacheConstants.DICT_REDIS_KEY + dictType);
            if (CollectionUtils.isNotEmpty(redisDictData)) {
                return redisDictData;
            } else {
                return Collections.emptyList();
            }
        }
    }

    /**
     * @description [字典数据同步Redis进行缓存]
     * @author ･ᴗ･
     */
    @GetMapping("/sysDictData/listDictCacheRedis")
    public void listDictCacheRedis() {
        sysDictDataService.listDictCacheRedis();
    }

}
